﻿/**
 *       Project: ServerLib
 *     Copyright: Copyright (C) 2008, Rob Kennedy
 *   Create Date: 2008-07-14 10:16 PM
 * Modified Date: 2008-07-14 10:16 PM    RK  Added comments
 *      Comments: Ignore SA1633.
 *      
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace ServerLib.Email
{
    using System.Text;
    using System.Net.Mail;

    /// --------------------------------------------------------------------
    /// Project	 : ServerLib
    /// Class	 : EmailHelper
    /// Inherits : None.
    /// --------------------------------------------------------------------
    /// <summary>
    /// Static functions used to help build email addresses, messages, etc.
    /// </summary>
    /// <authorname>Rob Kennedy</authorname>
    /// <remarks></remarks>
    /// --------------------------------------------------------------------
    public class EmailHelper
    {
        /// <summary>
        /// Removes &lt; and &gt; characters from a string
        /// </summary>
        /// <param name="emailAddress">The e-mail address string to parse</param>
        /// <returns>Returns a string without the specified characters</returns>
        public static string RemoveSigns(string emailAddress)
        {
            return emailAddress.Replace("<", string.Empty).Replace(">", string.Empty);
        }

        /// <summary>
        /// Breaks parts of an address line into appropriate properties of
        /// a returned MailAddress object
        /// </summary>
        /// <param name="emailAddressLine">The address line to parse</param>
        /// <returns>Returns a MailAddress Object containing name and/or e-mail address values</returns>
        public static MailAddress BreakAddressLine(string emailAddressLine)
        {
            string mailName = string.Empty;
            string mailAddress = string.Empty;
            string workBuffer = string.Empty;
            string lineBuffer = string.Empty;
            bool commentOn = false;
            int z = 0;
            
            // make a copy for our work buffer 
            workBuffer = emailAddressLine.Trim();
            
            // Possible Email address formats are as follows:
            // To: name@domain.com
            // To: John Doe <name@domain.com>
            // To: "Doe, John Q." <name@domain.com>
            // To: name@domain.com (The big guy)
            // To: John. (The Eliminator) Nerk@domain.com
            // To: "description" <dfdfd>

            // Method Process:
            // 1. All comments (...) are removed
            // 2. Check for " " if they exist, they wrap around our description
            // 3. If <> exist, then an address resides inside them and everything else is descriptive
            // 4. If no <> and no spaces, then the address is all that is left with no description
            
            // 1) go and parse out comments
            for (int i = 0; i < workBuffer.Length; i++)
            {
                if (workBuffer[i] == '(' && !commentOn)
                {
                    if (i > 0 && workBuffer[i - 1] != '/')
                    {
                        commentOn = true;
                    }
                }
                else if (workBuffer[i] == ')' && commentOn)
                {
                    if (i > 0 && workBuffer[i - 1] != '/')
                    {
                        commentOn = false;
                    }
                }
            
                // add to line buf 'cause we aint in a comment 
                if (!commentOn && workBuffer[i] != ')')
                {
                    lineBuffer += workBuffer[i];
                }
            }
        
            // copy our comment-free string over to work buffer 
            workBuffer = lineBuffer.Trim();

            // 2) go and parse through looking for description "..." if quotes exist
            if (workBuffer.IndexOf('"') > -1)
            {
                for (int q = 0; q < workBuffer.Length; q++)
                {
                    if (workBuffer[q] == '"')
                    {
                        if (q > 0 ? workBuffer[q - 1] != '/' : false)
                        {
                            commentOn = !commentOn;
                        }
                        else
                        {
                            commentOn = true;
                        }
                    }
                    else
                    {   
                        if (commentOn) 
                        {
                            // put this stuff into our name buffer
                            mailName += workBuffer[q];
                        }
                        else 
                        {
                            // add to line buf cause we aint in a comment
                            lineBuffer += workBuffer[q];
                        }
                    }
                }
            }

            // copy our description-free string over to work buffer 
            workBuffer = lineBuffer.Trim();

            // 3) If < > exist, then extract the email address from them
            int startIndex = workBuffer.IndexOf("<");
            int endIndex = workBuffer.LastIndexOf(">");

            if (startIndex > -1 && endIndex > -1)
            {
                if (startIndex > 0 ? (workBuffer[startIndex - 1] != '/' && workBuffer[endIndex - 1] != '/') : startIndex == 0)
                {
                    for (z = startIndex; z <= endIndex; z++)
                    {
                        if (workBuffer[z] != '<' && workBuffer[z] != '>')
                        {
                            mailAddress += workBuffer[z];
                        }
                    }
                }
            }
            else
            {
                // check to see if we have an address with a domain in here
                z = workBuffer.IndexOf("@");

                if (z > 0)
                {
                    startIndex = workBuffer.IndexOf(" ", z);
                    if (startIndex == -1)
                    {
                        startIndex = 0;
                    }
                    
                    endIndex = workBuffer.IndexOf(" ", z);
                    
                    if (endIndex == -1)
                    {
                        endIndex = workBuffer.Length;
                    }

                    mailAddress = workBuffer.Substring(startIndex, endIndex - startIndex);
                }
                else
                {
                    // no address with a domain so just assume whatever is left is an address
                    mailAddress = workBuffer;
                }
            }

            return new MailAddress(mailAddress, mailName, Encoding.UTF8);
        }
    }
}
